<?php
abstract class BaseTestController extends Controller
{
    protected $resourceId = 'SystemResource';
    protected $testsuiteSubfix = 'Testsuite';
    protected $testSubfix = 'Test';

    protected function GetLayout()
    {
        return new TestLayout();
    }

    public function Index($testsuite_class = null, $test_method = null)
    {
        if (!$testsuite_class)
        {
            $output = $this->RunAll();
        }
        else
        {
            if ($test_method)
            {
                $this->RunMethod($testsuite_class, $test_method);
                $this->title = $test_method;
            }
            else
            {
                $this->RunMethods($testsuite_class);
                $this->title = $testsuite_class;
            }
            $output = $this->Render();
        }
        return $output;
    }

    protected function RunAll()
    {
        $header = 'All Test Suites';
        $this->PushMessageHeader($header);

        $files = FileHandler::GetSubFiles($this->config->DIR_TESTSUITES);
        foreach($files as $file)
        {
            if (!String::EndWith($this->testsuiteSubfix.'.php', $file))
                continue;
            $class = FileHandler::ToClassName($file);
            $this->RunMethods($class);
        }

        $this->PopMessageHeader();

        $this->title = $header;
        return $this->Render();
    }

    protected function RunMethod($class, $method)
    {
        $obj = new $class();
        $obj->$method();
    }

    protected function GetTestMethods($class)
    {
        $class_methods = $this->GetPublicMethods($class);
        $test_methods = array();
        foreach ($class_methods as $method)
        {
            if (String::EndWith($this->testSubfix, $method))
                $test_methods[] = $method;
        }
        return $test_methods;
    }

    protected function RunMethods($class)
    {
        $test_methods = $this->GetTestMethods($class);
        if (count($test_methods)>0)
        {
            $class_url = $this->config->URL_DEFAULT."/$class";
            $this->PushMessageHeader("<a target='_blank' href='$class_url'>$class</a>");

            foreach ($test_methods as $method)
            {
                $method_url = $this->config->URL_DEFAULT."/$class/$method?expand";
                $this->PushMessageHeader("<a target='_blank' href='$method_url'>$method</a>");
                try
                {
                    $obj = new $class();
                    $obj->batchRun = true;
                    $obj->$method();
                }
                catch(Exception $ex)
                {
                    Log::LogError($ex->getMessage());
                }
                $this->PopMessageHeader();
            }
            $this->PopMessageHeader();
        }
    }

    protected function PushMessageHeader($header)
    {
        NestedMessage::Push(new TestHeaderMessage($header));
    }

    protected function PopMessageHeader()
    {
        NestedMessage::Pop();
    }

    protected function GetPublicMethods($class)
    {
        $class_methods = get_class_methods($class);
        $parent_class_methods = get_class_methods(get_parent_class($class));

        if (!is_array($class_methods)) $class_methods = array();
        if (!is_array($parent_class_methods)) $parent_class_methods = array();
        return array_diff($class_methods, $parent_class_methods);
    }
}
?>
